package com.josework.springhelloworld.controller;

import com.josework.springhelloworld.AjaxResponse;
import com.josework.springhelloworld.mapper.ArticleScan;
import com.josework.springhelloworld.model.Article;
import com.josework.springhelloworld.service.impl.ArticleServiceImpl;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: Joseph Xu
 * @Date: 2021/7/10 10:56
 */
@Slf4j
@RestController
@RequestMapping("/rest")
@Tag(name = "ArticleController", description = "API文档标签")
public class ArticleController {

    @Resource
    private ArticleServiceImpl articleService;

    //MyBatis流式查询
    @Autowired
    private ArticleScan articleScan;

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    @Autowired
    private PlatformTransactionManager transactionManager;

    //@RequestMapping(value = "/articles/{id}",method = RequestMethod.GET)
    @GetMapping("/articles/{id}")
    public AjaxResponse getArticle(@PathVariable("id") Long id){
//        Article article = Article.builder()
//                .id(1L)
//                .author("Joseph")
//                .content("Hello,world!")
//                .createTime(new Date()).build();
        Article article = articleService.getArticle(id);
        log.info("article info:"+article);

        return  AjaxResponse.success(article,"书籍Service，响应成功");

    }

    @GetMapping("/articles")
    public AjaxResponse getAllArticles(){
        List<Article> articleList = articleService.getAll();
        //TODO 如果为空抛出异常
        return AjaxResponse.success(articleList,"获取所有书籍，响应成功");

    }


    @Transactional
    @PostMapping("/articles")
    public AjaxResponse saveArticle(@RequestBody Article article){
//        if (article.getId() == null){
//            //TODO 抛出一个异常
//        }
        articleService.saveArticle(article);
        log.info("save article:"+ article);
        return AjaxResponse.success();
    }

    @PatchMapping("/articles")
    public AjaxResponse updateArticle(@RequestBody Article article){
        if (article.getId()==null){
            //TODO 抛出一个异常
        }
        articleService.updateArticle(article);
        log.info("update article"+article);
        return  AjaxResponse.success();

    }

    @Transactional
    @DeleteMapping("/articles/{id}")
    public AjaxResponse deleteArticle(@PathVariable("id")Long id){
        Article article = articleService.getArticle(id);
        articleService.deleteArticle(article);
//        int a = 10/0;
        log.info("delete article id:"+id);
        return  AjaxResponse.success();

    }

    // SqlSessionFactory 来手工打开数据库连接
    @GetMapping("articles/scan/0/{limit}")
    public Article scanArticles0(@PathVariable("limit") int limit) throws Exception {
        Article article = new Article();
        try (
                SqlSession sqlSession = sqlSessionFactory.openSession();  // 1
                Cursor<Article> cursor =
                        sqlSession.getMapper(ArticleScan.class).scan(limit)   // 2
        ) {
            cursor.forEach(e -> {
                article.setId(e.getId());
                article.setContent(e.getContent());
                article.setAuthor(e.getAuthor());
                article.setTitle(e.getTitle());
                article.setCreateTime(e.getCreateTime());
                article.setUpdateTime(e.getUpdateTime());

            });
        }
        return  article;
    }

    //TransactionTemplate 来执行一个数据库事务，这个过程中数据库连接同样是打开的
    @GetMapping("articles/scan/1/{limit}")
    public Article scanArticles1(@PathVariable("limit") int limit) throws Exception {
        Article article = new Article();
        TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
        transactionTemplate.execute(transactionStatus -> {
            try (Cursor<Article> cursor = articleScan.scan(limit)) {
                cursor.forEach(e -> {
                    article.setId(e.getId());
                    article.setContent(e.getContent());
                    article.setAuthor(e.getAuthor());
                    article.setTitle(e.getTitle());
                    article.setCreateTime(e.getCreateTime());
                    article.setUpdateTime(e.getUpdateTime());
                });
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        });
        return article;
    }

    @GetMapping("articles/scan/2/{limit}")
    @Transactional
    public List<Article> scanArticle3(@PathVariable("limit") int limit) throws Exception {
        List<Article> list = new ArrayList<>();
        try (Cursor<Article> cursor = articleScan.scan(limit)) {
            cursor.forEach(e -> {
                Article article = new Article();
                article.setId(e.getId());
                article.setContent(e.getContent());
                article.setAuthor(e.getAuthor());
                article.setTitle(e.getTitle());
                article.setCreateTime(e.getCreateTime());
                article.setUpdateTime(e.getUpdateTime());
                list.add(article);
            });
        };
        return list;
    }






}
